﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
using System.Threading;
using FinPlusInterfaces;
using FinPlusAssembler;

namespace FinPlusCompView
{
    //Note Prime use edit template columns use primative controls for data template
    public partial class FinPlusValueQuotePopup: FinPlusControl
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Test = true)]
        public override string TestString { get { return string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}", IsEnabled, QuoteSource, Instrument, Book, BuySell, Size, Quote, Counterparty); } }
        [State(Test = true)]
        public string ViewString { get { return string.Format("{0}|{1}|{2}|{3}|{4}", titleText, buySellText, tQuote, quoteSourceText, bookText); } }
        
        public new bool IsEnabled { get; private set; }
        public string QuoteSource { get; private set; }
        public string Instrument { get; private set; }
        public DateTime SettlementDate { get; private set; }
        public string Book { get; private set; }
        public string BuySell { get; private set; }
        public double Size { get; private set; }
        public double Quote { get; private set; }
        public string Counterparty { get; private set; }

        private enum Params { QuoteSource, QuoteInstrument, RateType, Rate, Counterparty, Settle, Book, BuySell, Size, Quote, LinkedId }
        private DispatcherTimer _timer;
        private TimeSpan _time = TimeSpan.FromSeconds(10);
        private Action<string> _callback;
        private IDPod _instrument;
        private FinPlusWindow _window;
        private IPod _quote;
        private string _reply;

        //construct
        public FinPlusValueQuotePopup(IPod quote, IDPod instrument, FinPlusWindow window, Action<string> callback, string reply, string linkedId)
        {
            InitializeComponent();
            DataContext = this;
            IsEnabled = true;
            countDown.Text = _time.ToString("c");
            _window = window;
            _quote = quote;
            _quote[Params.LinkedId.ToString()] = linkedId;
            _instrument = instrument;
            _callback = callback;
            _reply = reply;
            Load();
            IsValid = true;
        }

        //public
        public override void CmdExecute(IPod command) 
        {
            try
            {
                CmdCapture(command);

                //SaveAudit(pod.Name, new IBean[] { pod, _quote });

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.QuoteAcceptPublish: QuoteAcceptPublish(); break;
                    case Cmds.QuoteDeclinePublish: QuoteDeclinePublish(); break;
                    case Cmds.QuoteExecute: QuoteExecute(); break;
                    case Cmds.QuoteClose: 
                    case Cmds.QuoteAccept:
                    case Cmds.QuoteDecline:
                    case Cmds.QuoteMissed: Stop(); break;
                    default: throw new Exception(string.Format("cmd not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
               IsValid = Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        //public
        public void Load()
        {
            try
            {
                QuoteSource = _quote[Params.QuoteSource.ToString()].ToString();
                Instrument = _quote[Params.QuoteInstrument.ToString()].ToString();
                SettlementDate = (DateTime)_quote.Value(Params.Settle.ToString());
                Book = _quote[Params.Book.ToString()].ToString();
                Quote = (double)_quote.Value(Params.Quote.ToString());
                Counterparty = _quote[Params.Counterparty.ToString()].ToString();
                Size = (double)_quote.Value(Params.Size.ToString());
                Id = _quote[PodField.Id.ToString()].ToString();

                if (_quote[Params.RateType.ToString()].ToString().Equals(Params.Rate.ToString()))
                    tQuote.SetBinding(FinPlusValueShiftTextBox.TextProperty, new Binding(Params.Quote.ToString()) { StringFormat = "{0:P2}" });
                else
                    tQuote.SetBinding(FinPlusValueShiftTextBox.TextProperty, new Binding(Params.Quote.ToString()));

                var command = _quote[PodField.Type.ToString()].ToString().EnumParse<Cmds>(Cmds.Exception);
                var buySell = _quote[Params.BuySell.ToString()].ToString();
                BuySell = command == Cmds.QuoteExecutePublish ? buySell : buySell.Equals("Buy") ? "Sell" : "Buy";

                switch (command)
                {
                    case Cmds.Quote: StartQuoteExecute(); break;
                    case Cmds.QuoteMissed: StartQuoteMissed(); break;
                    case Cmds.QuoteDecline: StartQuoteDecline(); break;
                    case Cmds.QuoteAccept: StartQuoteAccept(); break;
                    case Cmds.QuoteExecutePublish: StartQuoteExecutePublish(); break;
                    case Cmds.Exception: break;
                }
            }
            catch (Exception e)
            {
                IsValid = Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        //private
        private void QuoteExecute()
        {
            _quote.Get(PodField.Type.ToString()).Update(_quote.Name = Cmds.QuoteExecute.ToString());
            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
            _callback.Invoke(_quote.ToString());
            Stop();
        }

        private void QuoteAcceptPublish()
        {
            _quote.Get(PodField.Type.ToString()).Update(_quote.Name = Cmds.QuoteAcceptPublish.ToString());
            _instrument.SetValue(_reply, _quote.ToString(), User, DateTime.Now);
            Stop();
        }

        private void QuoteDeclinePublish()
        {
            _quote.Get(PodField.Type.ToString()).Update(_quote.Name = Cmds.QuoteDeclinePublish.ToString());
            _instrument.SetValue(_reply, _quote.ToString(), User, DateTime.Now);
            Stop();
        }

        private void StartQuoteExecute()
        {
            bTraderExecute.Visibility = bTraderClose.Visibility = Visibility.Visible;
            if (Permissions.Get(Params.QuoteInstrument.ToString(), PodField.Id.ToString(), Id).CanWrite)
                bTraderExecute.IsEnabled = bTraderClose.IsEnabled = true;
            StartTimer();
        }

        private void StartQuoteMissed()
        {
            bTraderMissed.Visibility = Visibility.Visible;
            bTraderMissed.IsEnabled = true;
        }

        private void StartQuoteAccept()
        {
            bVendorAccept.Visibility =  Visibility.Visible;
            bVendorAccept.IsEnabled = true;
        }

        private void StartQuoteDecline()
        {
            bVendorDecline.Visibility = Visibility.Visible;
            bVendorDecline.IsEnabled = true;
        }

        private void StartQuoteExecutePublish()
        {
            bTraderAccept.Visibility = bTraderDecline.Visibility = Visibility.Visible;
            if (Permissions.Get(Params.QuoteInstrument.ToString(), PodField.Id.ToString(), Id).CanWrite)
                bTraderAccept.IsEnabled = bTraderDecline.IsEnabled = true;

            StartTimer();
        }

        private void StartTimer()
        {
            try
            {
                _timer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, delegate
                {
                    countDown.Text = _time.ToString("c");
                    if (_time <= TimeSpan.Zero)
                        _window.Close();
                    _time = _time.Add(TimeSpan.FromSeconds(-1));
                }, this.Dispatcher);
                _timer.Start();
            }
            catch (Exception e)
            {
                Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        private void Stop()
        {
            if(_timer !=null)
                _timer.Stop();
            _window.Close();
        }

        //cmds
        private enum Cmds { Quote, QuoteExecute, QuoteMissed, QuoteDecline, QuoteAccept, QuoteClose, QuoteAcceptPublish, QuoteDeclinePublish, QuoteExecutePublish, Exception }

        //events
        private void Title_MouseDown(object s, MouseButtonEventArgs a){ _window.DragMove(); }
    }
}